package com.xindacloud.sms.console.config;


import com.xindacloud.sms.console.constant.SessionKeys;
import com.xindacloud.sms.console.system.properties.EndpointProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
import org.springframework.session.web.http.HttpSessionIdResolver;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.*;

@Slf4j
@Configuration
@EnableConfigurationProperties(EndpointProperties.class)
public class WebMvcConfig implements WebMvcConfigurer {

    @Value("${server.error.path:${error.path:/error}}")
    private String errorPath;

    @Bean
    public static ConfigureRedisAction configureRedisAction() {
        return ConfigureRedisAction.NO_OP;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        template.setValueSerializer(new StringRedisSerializer());
        template.setDefaultSerializer(new StringRedisSerializer());

        return template;
    }

    @Bean
    public HttpSessionIdResolver httpSessionStrategy() {
        return new HeaderHttpSessionIdResolver(SessionKeys.SMS_TOKEN);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
                .addInterceptor(new AuthIntercept())
                .addPathPatterns("/**")
                .excludePathPatterns("/api/v1/sms-user/login", "/api/v1/sms-user/logout")
                //.excludePathPatterns("/api/v1/sms-website-info/**", "/api/v1/sms-ui-content/**","/api/v1/sms-friendship-link/**")
                //.excludePathPatterns("/api/v1/sms-website-info/**", "/api/v1/sms-ui-content/**","/api/v1/sms-friendship-link/**")
                /*.excludePathPatterns("/api/v1/sms-user/**","/api/v1/sms-pricing/**")
                .excludePathPatterns("/api/v1/sms-system-menu/**","/api/v1/sms-agent/agents/**","/api/v1/sms-account-transation/**")*/
                .excludePathPatterns(errorPath)
                .excludePathPatterns("/test")
                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");

    }

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setMaxAge(60 * 60 * 24 * 30L);
        config.addExposedHeader(SessionKeys.SMS_TOKEN);
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }


    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Override
    public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }

}
